package com.atguigu.srb.servicesms.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.guli.common.util.RandomUtils;
import com.atguigu.guli.common.util.RegexValidateUtils;
import com.atguigu.srb.base.dto.SmsDTO;
import com.atguigu.srb.base.exception.SrbException;
import com.atguigu.srb.base.result.ResponseEnum;
import com.atguigu.srb.base.util.HttpUtils;
import com.atguigu.srb.base.util.SrbAssert;
import com.atguigu.srb.servicesms.config.SmsProperties;
import com.atguigu.srb.servicesms.feign.CoreClient;
import com.atguigu.srb.servicesms.service.SmsService;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
@EnableConfigurationProperties(SmsProperties.class)
public class SmsServiceImlp implements SmsService {

    @Resource
    StringRedisTemplate stringRedisTemplate;

    @Resource
    CoreClient coreClient;
//    @Resource
//    static
//    SmsProperties smsProperties;

    @Override
    public void sendSms(String mobile, Integer type) {
        //1、手机号码格式校验：正则表达式
        SrbAssert.AssertNotTrue(!RegexValidateUtils.checkCellphone(mobile), ResponseEnum.MOBILE_ERROR);

        //type=1 注册时 校验手机号码是否已经被占用
        if(type==1){
            Map<String, Object> result = coreClient.isUsed(mobile).getData();
            SrbAssert.AssertNotTrue((CollectionUtils.isEmpty(result)||!(Boolean)(result.get("flag"))),
                    ResponseEnum.MOBILE_EXIST_ERROR);
        }

        //2、手机号码发送频率：5分钟内不能重复获取、一天内只能获取5条
        //5分钟内不能重复获取 key
        String timeLimtKey = "sms:limit:" + type + ":" + mobile;
        SrbAssert.AssertNotTrue(stringRedisTemplate.hasKey(timeLimtKey),ResponseEnum.ALIYUN_SMS_LIMIT_CONTROL_ERROR);
        //一天内只能获取5条
        String countLimitKey = "sms:count:" + type + ":" + mobile;
        if (stringRedisTemplate.hasKey(countLimitKey)){
            //存在发送短信的次数：获取次数
            String countStr = stringRedisTemplate.opsForValue().get(countLimitKey);
            SrbAssert.AssertNotTrue(Integer.parseInt(countStr)>=5,ResponseEnum.ALIYUN_SMS_DAY_LIMIT_CONTROL_ERROR);
        }else {
            //countLimitKey 次数数据不存在 初始化为0 并设置过期时间
            stringRedisTemplate.opsForValue().set(countLimitKey,"0",24,TimeUnit.HOURS);
        }

        //3、生成验证码发送短信
        String code = RandomUtils.getSixBitRandom();
        //sendMessage(mobile, code);
        //4、更新手机号码获取验证码的频率
        //缓存验证码到redis中：使用type区分验证码使用的类型
        stringRedisTemplate.opsForValue().set("sms:code:"+type+":"+mobile,code,5,TimeUnit.MINUTES);
        //更新验证码发送的次数
        //如果手机号第一次获取验证码increment 次数默认为0+1
        stringRedisTemplate.opsForValue().increment(countLimitKey);
        //用手机号码拼接key 缓存一过期时间为5分钟的数据
        stringRedisTemplate.opsForValue().set(timeLimtKey,"1",5, TimeUnit.MINUTES);
    }

    @Override
    public void mqSendMsg(SmsDTO smsDTO) {
        String mobile = smsDTO.getMobile();
        List<String> params = smsDTO.getParams();
        Integer type = smsDTO.getType();
        String content = getMsgContent(type,params);

        String host = SmsProperties.HOST;
        String path = SmsProperties.PATH;
        String method = SmsProperties.METHOD;
        String appcode = SmsProperties.APPCODE;
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("mobile", mobile);
        querys.put("content", content);


        try {
            HttpResponse response = HttpUtils.doGet(host, path, method, headers, querys);
            System.out.println(response.toString());
            //获取response的body：解析响应体
            String resultJson = EntityUtils.toString(response.getEntity(),"UTF-8");
            Map map = JSON.parseObject(resultJson, Map.class);
            String resultCode = map.get("error_code").toString();
            if ("0".equals(resultCode)){
                //短信发送成功
                System.out.println("短信发送成功:"+ resultJson);
            }else {
                //短信发送失败
                System.out.println("短信发送失败:"+ resultJson);
                throw new SrbException(ResponseEnum.ALIYUN_SMS_ERROR);
            }
            //System.out.println(EntityUtils.toString(response.getEntity()));
        } catch (Exception e) {
            throw new SrbException(ResponseEnum.ALIYUN_SMS_ERROR);
        }


    }

    private String getMsgContent(Integer type, List<String> params) {
        //"【智能云】您的验证码是"+ code +"。如非本人操作，请忽略本短信"
        String content = null;
        switch (type){
            case 1:
                //注册短信

                break;
            case 2:
                //登录短信
                content = "【智能云】您的验证码是"+ params.get(0) +"。如非本人操作，请忽略本短信";
                break;
            case 3:
                //充值成功短信
                content = "【智能云】您的验证码是"+ params.get(0) +"。如非本人操作，请忽略本短信";
                break;
            case 4:
                //提款成功短信
                content = "【智能云】您的验证码是"+ params.get(0) +"。如非本人操作，请忽略本短信";
                break;
            default:
                //默认短信通知
                content = "【智能云】您的验证码是"+ params.get(0) +"。如非本人操作，请忽略本短信";
                break;
        }
        return content;
    }

    private static void sendMessage(String mobile, String code) {
        String host = SmsProperties.HOST;
        String path = SmsProperties.PATH;
        String method = SmsProperties.METHOD;
        String appcode = SmsProperties.APPCODE;
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        Map<String, String> querys = new HashMap<String, String>();
        querys.put("mobile", mobile);
        querys.put("content", "【智能云】您的验证码是"+ code +"。如非本人操作，请忽略本短信");


        try {
            HttpResponse response = HttpUtils.doGet(host, path, method, headers, querys);
            System.out.println(response.toString());
            //获取response的body：解析响应体
            String resultJson = EntityUtils.toString(response.getEntity(),"UTF-8");
            Map map = JSON.parseObject(resultJson, Map.class);
            String resultCode = map.get("error_code").toString();
            if ("0".equals(resultCode)){
                //短信发送成功
                System.out.println("短信发送成功:"+ resultJson);
            }else {
                //短信发送失败
                System.out.println("短信发送失败:"+ resultJson);
                throw new SrbException(ResponseEnum.ALIYUN_SMS_ERROR);
            }
            //System.out.println(EntityUtils.toString(response.getEntity()));
        } catch (Exception e) {
            throw new SrbException(ResponseEnum.ALIYUN_SMS_ERROR);
        }
    }
}
